package com.ruoyi.project.knowledge.algorithms;

import com.ruoyi.project.fusion.utils.ComputeUtils;
import com.ruoyi.project.knowledge.domain.OverallAggScores;
import com.ruoyi.project.knowledge.domain.OverallScores;

import java.util.ArrayList;
import java.util.List;

public class DataOptimizationAlgorithm {

    private static final float HUMAN_RESOURCE_WEIGHT = 0.15f;
    private static final float BUSINESS_STATUS_WEIGHT = 0.15f;
    private static final float MATERIAL_MANAGEMENT_WEIGHT = 0.15f;
    private static final float QUALITY_WEIGHT = 0.15f;
    private static final float PRICE_WEIGHT = 0.15f;
    private static final float SERVICE_WEIGHT = 0.15f;
    private static final float TECHNOLOGY_WEIGHT = 0.1f;

    public List<OverallScores> compute(List<OverallAggScores> overallAggScores, int priorityType) {
        float[] weights = adjustWeights(priorityType);
        List<OverallScores> overallScoresList = new ArrayList<>();

        for (OverallAggScores scores : overallAggScores) {
            float finalScore = scores.getHumanResourceScores() * weights[0]
                    + scores.getBusinessStatusScores() * weights[1]
                    + scores.getMaterialManagementScores() * weights[2]
                    + scores.getQualityScores() * weights[3]
                    + scores.getPriceScores() * weights[4]
                    + scores.getServiceScores() * weights[5]
                    + scores.getTechnologyScores() * weights[6];

            OverallScores overallScores = new OverallScores();
            overallScores.setChainType(scores.getChainType());
            overallScores.setEnterpriseName(scores.getEnterpriseName());
            overallScores.setScenario(scores.getScenario());
            overallScores.setProduct(scores.getProduct());
            overallScores.setEvent(scores.getEvent());
            overallScores.setScore(ComputeUtils.roundToTwoDecimalPlaces(finalScore));
            overallScoresList.add(overallScores);
        }
        return overallScoresList;
    }

    private float[] adjustWeights(int priorityType) {
        float[] weights = new float[7];
        weights[0] = HUMAN_RESOURCE_WEIGHT;
        weights[1] = BUSINESS_STATUS_WEIGHT;
        weights[2] = MATERIAL_MANAGEMENT_WEIGHT;
        weights[3] = QUALITY_WEIGHT;
        weights[4] = PRICE_WEIGHT;
        weights[5] = SERVICE_WEIGHT;
        weights[6] = TECHNOLOGY_WEIGHT;
        if (priorityType == 0) {
            return weights;
        }

        if (priorityType >= 1 && priorityType <= 7) {
            float priorityWeight = weights[priorityType - 1] * 2;
            float remainingTotalWeight = 1 - priorityWeight;
            float sumOtherWeights = 0;

            for (int i = 0; i < weights.length; i++) {
                if (i != priorityType - 1) {
                    sumOtherWeights += weights[i];
                }
            }

            for (int i = 0; i < weights.length; i++) {
                if (i != priorityType - 1) {
                    weights[i] = (weights[i] / sumOtherWeights) * remainingTotalWeight;
                } else {
                    weights[i] = priorityWeight;
                }
            }
        }

        return weights;
    }
}